package cn.kgc.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.ReUtil;
import cn.kgc.base.BaseInfoProperties;
import cn.kgc.entity.Users;
import cn.kgc.excpetion.GraceException;
import cn.kgc.form.LoginOrRegisterForm;
import cn.kgc.grace.result.GraceJSONResult;
import cn.kgc.grace.result.ResponseStatusEnum;
import cn.kgc.message.SmsMessage;
import cn.kgc.service.UsersService;
import cn.kgc.util.MessageinfoSender;
import cn.kgc.utils.JwtUtil;
import cn.kgc.vo.UsersVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

import static cn.kgc.base.SystemConstant.LOGIN_TYPE_APP;

/**
 * @author wangyue
 * @version 1.0
 */
@RestController
@RequestMapping("/passport")
@Api(tags = "用户认证")
@Validated
public class PassportController extends BaseInfoProperties {
    @Resource
    private UsersService usersService;
    @Resource
    private JwtUtil jwtUtil;
    @Resource
    private MessageinfoSender messageinfoSender;

    @PostMapping("/loginOrRegister")
    @ApiOperation(value = "一键登录注册")
    public GraceJSONResult loginOrRegister(
            @Validated  @RequestBody LoginOrRegisterForm form
    ){
        //1 判断手机验证码是否正确
        String key=MOBILE_SMSCODE+form.getMobile();
        //用户输入的手机验证码 是否和 Redis中存储的当前手机的验证码相等,如果不相等则验证码错误
        if(!form.getSmsCode().equals(redisUtil.get(key))){
           GraceException.display(ResponseStatusEnum.SMS_CODE_ERROR);
        }
        //2 判断用户是否存在
        Users users= usersService.login(form.getMobile());
        if(users==null){
            //如果用户不存在,则注册用户并且给用户初始化一份简历
            users=usersService.registerAndInitResume(form.getMobile());
        }
        //3 删除验证码
        redisUtil.delete(key);
        //4 生成登录令牌,将用户信息和登录令牌返回给前端。
        //假设用户A是一个普通用户。登录成功以后 后端会颁发一个登录的令牌。他拿着这个令牌 只能用于手机端的APP登录。用户A不能用这个令牌登录招聘管理系统的后台,所以我们需要区分下登录的类型。
        String token= jwtUtil.createToken(users.getId(),LOGIN_TYPE_APP);
        UsersVO usersVO=new UsersVO();
        BeanUtil.copyProperties(users,usersVO);
        usersVO.setToken(token);
        //手机号脱敏
        usersVO.setMobile(DesensitizedUtil.mobilePhone(users.getMobile()));
        return GraceJSONResult.ok(usersVO);
    }

    @GetMapping("/sendSmsCode")
    @ApiOperation(value = "发送短信验证")
    @ApiImplicitParams({
          @ApiImplicitParam(name = "mobile",value = "手机号",required = true)
    })
    public GraceJSONResult  sendCode(String mobile){
         //1 判断手机号格式是否正确
        boolean validate= ReUtil.isMatch("^1\\d{10}$",mobile);
        if(!validate){
            GraceException.display(ResponseStatusEnum.SMS_MOBILE_ERROR);
        }
        //2 判断手机号是内否在60s内获得过短信验证码,如果获得过直接返回错误信息
        String key=MOBILE_SMSCODE+mobile;
        String code= RandomUtil.randomNumbers(6);
        //如果key不存在,保存key和value到redis中返回true。如果key存在不保存,返回false
        boolean result= redisUtil.setIfAbsent(key,code,300,TimeUnit.SECONDS);
        if(!result){
            GraceException.display(ResponseStatusEnum.SMS_NEED_WAIT_ERROR);
        }
        //3 将消息发送到RabbitMQ中
        SmsMessage smsMessage=new SmsMessage();
        smsMessage.setPhone(mobile);
        smsMessage.setCode(code);
        messageinfoSender.sendMessage(
                "smsMessageExchange","smsMessageRoutingKey",smsMessage
        );
        //4 返回结果
        return GraceJSONResult.ok();
    }
}